import Config from '@/utils/Config'
import { Base64 } from 'js-base64'
import { getToken } from '@/store/Store'
import store from '@/store/'

function $showLoading () {
  uni.showLoading({
    title: '加载中',
    mask: true
  })
  setTimeout(() => {
    uni.hideLoading();
  }, 10000);
}

function $showTokenLoading () {
  uni.showLoading({
    title: '安全验证中...',
    mask: true
  })
  setTimeout(() => {
    uni.hideLoading();
  }, 15000);
}

function $closeLoading () {
  uni.hideLoading()
}

/**
 * 初始化配置信息
 * @param config
 * @private
 */
function $config (config) {
  if (typeof (config.loading) === 'undefined') config.loading = true
  if (typeof (config.tips) === 'undefined') config.tips = true
}

/**
 * 请求前Token 处理
 * @param params
 * @returns {Promise<any>}
 * @private
 */
function $request (params) {
  const token = getToken()
  const config = params.config || {}
  $config(config)
  params.config = config
  const { header = {} } = params
  params.header = header
  if (config.loading && !params.url.endsWith('token')) { $showLoading() } else if (config.loading) { $showTokenLoading() }
  if (params.url.endsWith('token')) {
    header.Authorization = `Basic ${Base64.encode(`${Config.clientId}:${Config.clientSecret}`)}`
  } else if (token) {
    header.Authorization = `${token}`
  }
  return request(params)
}

/**
 * 真正的请求
 * @param params
 * @returns {Promise<any>}
 */
function request (params) {
  return new Promise((resolve, reject) => {
    const { config } = params
    let { url, method = 'GET', header } = params
    config.method = params.method
    url = Config.baseRequestUrl + url
    const _params = { url, method }
    if (header) _params.header = header
    _params.fail = err => errorHandle(reject, err.message || '非法请求', config)
    if (method === 'UPLOAD') {
      const { path, name, formData, files, file } = params
      delete _params.method
      if (path) _params.filePath = path
      if (name) _params.name = name
      if (files) _params.files = files
      if (file) _params.file = file
      if (formData) _params.formData = formData
      _params.success = ({ statusCode, data }) => successHandle({ resolve, reject, data, statusCode, config })
      uni.uploadFile(_params)
    } else if (method === 'DOWNLOAD') {
      _params.success = ({ tempFilePath, statusCode }) => successHandle({
        resolve,
        reject,
        tempFilePath,
        statusCode,
        config
      })
      uni.downloadFile(_params)
    } else {
      const { data, dataType, responseType } = params
      if (data) _params.data = data
      if (dataType) _params.dataType = dataType
      if (responseType) _params.responseType = responseType
      _params.success = ({ data, statusCode, header }) => successHandle({
        resolve,
        reject,
        data,
        statusCode,
        header,
        config
      })
      uni.request(_params)
    }
  })
}

/**
 * 请求成功的回调
 * @param params
 */

function successHandle (params) {
  const { resolve, statusCode, config, data } = params
  if (config.loading) $closeLoading()
  if (statusCode === 200) {
    const method = config.method
    if (method === 'DOWNLOAD') {
      resolve(params.tempFilePath)
    } else {
      let { data, header } = params
      if (method === 'UPLOAD') if (data) data = JSON.parse(data)
      if (data.code === 200) {
        resolve(data.data, header)
      } else if (data.code === 401) {
        store.dispatch('logout')
        uni.navigateTo({ url: '/pages/index/login' })
      } else {
        // debugger;
        resolve(data, header)
        // errorHandle(reject, data.msg || '未知错误', config)
      }
    }
  } else if (statusCode === 401) {
    uni.getNetworkType({
      success: function (res) {
        console.log(res.networkType);// 网络类型 wifi、2g、3g、4g、ethernet、unknown、none
        if (res.networkType === 'none') {
          console.log('当前无网络');
        } else {
          store.dispatch('logout')
          uni.navigateTo({ url: '/pages/index/login' })
        }
      }
    });
  } else if (statusCode === 400) {
    uni.showToast({
      icon: 'none',
      title: data.error_description
    })
  } else {
    uni.showToast({
      icon: 'none',
      title: data.msg
    })
  }
}

/**
 * 请求失败回调
 * @param err
 */
function errorHandle (reject, msg, config) {
  uni.getNetworkType({
    success: function (res) {
      console.log(res.networkType);// 网络类型 wifi、2g、3g、4g、ethernet、unknown、none
      if (res.networkType === 'none') {
        console.log('当前无网络');
      } else {
        store.dispatch('logout')
        uni.reLaunch({ url: '/pages/index/login' })
      }
    }
  });
}

/**
 * 发起GET请求
 * @param url 请求地址
 * @param params 请求参数
 * @param config 请求配置
 *  loading: boolean 是否显示loading, 默认true
 *  tips: boolean 错误时是否提示, 默认true
 *  dataType: String 返回的数据格式 默认 json; 非json时不对返回数据做JSON转换
 *  responseType: String 响应的数据类型 默认text;  可选值arraybuffer.
 * @param header 请求头
 *  参考http请求的headers
 *  注:
 *  不可设置Referer.
 *  content-type: 默认 application/json
 */
export const get = ({ url, params = {}, config = {}, header }) => $request({
  url,
  method: 'GET',
  data: params,
  header,
  dataType: config.dataType,
  responseType: config.responseType,
  config
})

/**
 * 发起POST请求
 * @param url 请求地址
 * @param params 请求参数
 * @param config 请求配置
 *  loading: boolean 是否显示loading, 默认true
 *  tips: boolean 错误时是否提示, 默认true
 *  dataType: String 返回的数据格式 默认 json; 非json时不对返回数据做JSON转换
 *  responseType: String 响应的数据类型 默认text;  可选值arraybuffer.
 * @param header 请求头
 *  参考http请求的headers
 *  注:
 *  不可设置Referer.
 *  content-type: 默认 application/json
 */
export const post = ({ url, params = {}, config = {}, header }) => $request({
  url: url,
  method: 'POST',
  data: params,
  header,
  dataType: config.dataType,
  responseType: config.responseType,
  config
})

/**
 * 上传文件
 * @param url 请求地址
 * @param params 附带的额外参数
 * @param config 配置项
 *  loading: boolean 是否显示loading, 默认true
 *  tips: boolean 错误时是否提示, 默认true
 * @param header 请求头
 *  参考http请求的headers
 *  注:
 *  不可设置Referer.
 *  content-type: 默认 multipart/form-data
 * @returns {Promise<any>}
 */
export const upload = ({ url, params = {}, config = {}, header }) => $request({
  url,
  method: 'UPLOAD',
  path: params.path,
  name: params.name,
  files: params.files,
  file: params.file,
  formData: params.formData,
  header,
  config
})

/**
 * 下载文件
 * @param url 请求地址
 * @param config 配置项
 *  loading: boolean 是否显示loading, 默认true
 *  tips: boolean 错误时是否提示, 默认true
 * @param header 请求头
 *  参考http请求的headers
 *  注:
 *  不可设置Referer.
 * @returns {Promise<any>}
 */
export const download = ({ url, config = {}, header }) => $request({
  url,
  method: 'DOWNLOAD',
  header,
  config
})
